{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using Opik with Pydantic AI\n",
    "\n",
    "Opik integrates with [Pydantic AI](https://ai.pydantic.dev/) to provide a simple way to log your agent calls.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating an account on Comet.com\n",
    "\n",
    "[Comet](https://www.comet.com/site?from=llm&utm_source=opik&utm_medium=colab&utm_content=openai&utm_campaign=opik) provides a hosted version of the Opik platform, [simply create an account](https://www.comet.com/signup?from=llm&utm_source=opik&utm_medium=colab&utm_content=aisuite&utm_campaign=opik) and grab you API Key.\n",
    "\n",
    "> You can also run the Opik platform locally, see the [installation guide](https://www.comet.com/docs/opik/self-host/overview/?from=llm&utm_source=opik&utm_medium=colab&utm_content=aisuite&utm_campaign=opik) for more information.\n",
    "\n",
    "## Setting up the logging\n",
    "\n",
    "Pydantic AI uses the logfire library to log traces to Opik. Before logging our agent calls, we will configure the integration\n",
    "by installing the required libraries and setting the correct environment variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m25.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.0.1\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "# Install the required libraries\n",
    "%pip install --upgrade --quiet pydantic-ai logfire 'logfire[httpx]' nest_asyncio\n",
    "\n",
    "# Configure the logging to Opik Cloud\n",
    "os.environ[\"OTEL_EXPORTER_OTLP_ENDPOINT\"] = (\n",
    "    \"https://www.comet.com/opik/api/v1/private/otel\"\n",
    ")\n",
    "os.environ[\"OTEL_EXPORTER_OTLP_HEADERS\"] = (\n",
    "    \"Authorization=your-api-key,Comet-Workspace=default\"  # Make sure to replace your API key\n",
    ")\n",
    "\n",
    "# If you are using a self-hosted instance, you can use:\n",
    "# os.environ[\"OTEL_EXPORTER_OTLP_ENDPOINT\"] = \"http://localhost:5173/api/v1/private/otel\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that everything is configured correctly, we can enable the logging:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Attempting to instrument while already instrumented\n"
     ]
    }
   ],
   "source": [
    "import logfire\n",
    "\n",
    "logfire.configure(\n",
    "    send_to_logfire=False,\n",
    ")\n",
    "logfire.instrument_httpx(capture_all=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Logging your first trace\n",
    "\n",
    "Before we log our first trace, we are going to configure the environment and ensure\n",
    "the code runs in a Notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "import os\n",
    "import getpass\n",
    "\n",
    "if \"OPENAI_API_KEY\" not in os.environ:\n",
    "    os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter your OpenAI API key: \")\n",
    "\n",
    "nest_asyncio.apply()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11:57:41.825 POST api.openai.com/v1/chat/completions\n",
      "11:57:43.481 Reading response body\n",
      "\"Hello, World!\" originates from the book \"The C Programming Language\" by Brian Kernighan and Dennis Ritchie, often used as a simple program to illustrate basic syntax in programming.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "from pydantic_ai import Agent\n",
    "\n",
    "agent = Agent(\n",
    "    \"openai:gpt-4o\",\n",
    "    system_prompt=\"Be concise, reply with one sentence.\",\n",
    ")\n",
    "\n",
    "result = agent.run_sync('Where does \"hello world\" come from?')\n",
    "print(result.data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![pydantic-ai Integration](https://raw.githubusercontent.com/comet-ml/opik/main/apps/opik-documentation/documentation/fern/img/cookbook/pydantic-ai_trace_cookbook.png)\n",
    "\n",
    "*Note:* This screenshot was taken for a more complex agent but you should see a very trace."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py312_llm_eval",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
